/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.rpc;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.DateUtils;
import com.je.common.base.util.StringUtil;
import com.je.common.base.util.TreeUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.rbac.service.IconType;
import com.je.rbac.service.role.RbacRoleService;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.je.rbac.exception.RoleException;
import com.je.rbac.service.grant.DevelopProductService;
import org.springframework.transaction.annotation.Transactional;

@RpcSchema(schemaId = "roleRpcService")
public class RoleRpcServiceImpl implements RoleRpcService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private BeanService beanService;
    @Autowired
    private DevelopProductService developProductService;
    @Autowired
    private RbacRoleService rbacRoleService;

    @Override
    @Transactional(rollbackFor = {RuntimeException.class})
    public boolean createProductRoleAndGrant(String productId, String productName) {
        developProductService.createProductRole(productId,productName);
        try {
            developProductService.grant(productId);
        }catch (RoleException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public JSONTreeNode buildRoleTreeByRoleIds(String roleIds,Boolean develop) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        DynaBean table = beanService.getResourceTable("JE_RBAC_ROLE");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);
        List<DynaBean> beanList= null;
        StringBuffer sb = new StringBuffer();
        sb.append(" AND ROLE_DEVELOP = '" + (develop ? "1" : "0") + "'");
        sb.append(" AND JE_RBAC_ROLE_ID != 'ROOT'");
        sb.append(" ORDER BY SY_TREEORDERINDEX ASC");
        if(!Strings.isNullOrEmpty(roleIds)){
            List<String> roleIdList = Splitter.on(",").splitToList(roleIds);
            beanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder().in("JE_RBAC_ROLE_ID",roleIdList).apply(sb.toString()));
        }else{
            beanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder().apply(sb.toString()));
        }
        if(null == beanList){
            return rootNode;
        }

        for (DynaBean eachBean : beanList) {
            JSONTreeNode node = null;
                if ("ROOT".equals(eachBean.get("SY_PARENT"))) {
                    node = buildTreeNode(template, rootNode.getId(), eachBean);
                }
                if (node != null) {
                    rootNode.getChildren().add(node);
                }
        }
        //递归形成树形结构
        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, beanList);
        }
        return rootNode;
    }

    private void recursiveJsonTreeNode(JSONTreeNode template, JSONTreeNode rootNode, List<DynaBean> list) {
        if (list == null || list.isEmpty()) {
            return;
        }

        JSONTreeNode treeNode;
        for (DynaBean eachBean : list) {
            if (!Strings.isNullOrEmpty(rootNode.getId()) && rootNode.getId().equals(eachBean.get("SY_PARENT"))) {
                treeNode = buildTreeNode(template, rootNode.getId(), eachBean);
                rootNode.getChildren().add(treeNode);
            }
        }
        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            rootNode.setLeaf(true);
            return;
        }
        rootNode.setLeaf(false);
        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, list);
        }

    }

    /**
     * 构建树形节点
     *
     * @param template     模板
     * @param parentNodeId 父节点ID
     * @param bean         当前bean
     * @return
     */
    private JSONTreeNode buildTreeNode(JSONTreeNode template, String parentNodeId, DynaBean bean) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.get("JE_RBAC_ROLE_ID").toString());
        node.setParent(parentNodeId);
        node.setLeaf(true);
        if (StringUtil.isNotEmpty(template.getText())) {
            node.setText(getString(bean.get(template.getText())));
        }
        if (StringUtil.isNotEmpty(template.getCode())) {
            node.setCode(getString(bean.get(template.getCode())));
        }
        //节点信息
        if (StringUtil.isNotEmpty(template.getNodeInfo())) {
            node.setNodeInfo(getString(bean.get(template.getNodeInfo())));
        }
        //节点信息类型
        if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
            node.setNodeInfoType(getString(bean.get(template.getNodeInfoType())));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(getString(bean.get(template.getNodeType())));
        }
        //节点路径
        if (StringUtil.isNotEmpty(template.getNodePath())) {
            node.setNodePath(getString(bean.get(template.getNodePath())));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(getString(bean.get(template.getDisabled())));
        }
        //树形排序
        if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
            node.setTreeOrderIndex(getString(bean.get(template.getTreeOrderIndex())));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(getString(bean.get(template.getNodeType())));
        }
        //图标样式
        if (StringUtil.isNotEmpty(template.getIcon())) {
            node.setIcon(getString(bean.get(template.getIcon())));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(getString(bean.get(template.getDisabled())));
        } else {
            node.setDisabled("0");
        }
        //描述
        if (StringUtil.isNotEmpty(template.getDescription())) {
            node.setDescription(getString(bean.get(template.getDescription())));
        }
        //排序
        if (StringUtil.isNotEmpty(template.getOrderIndex())) {
            node.setOrderIndex(bean.get(template.getOrderIndex()) + "");
        }
        node.setBean(bean.getValues());
        return node;
    }

    private String getString(Object obj){
        if(obj == null){
            return null;
        }
        return obj.toString();
    }

    @Override
    public List<String> findRoleUserIds(List<String> roleIds) {
        return rbacRoleService.findRoleUserIds(roleIds);
    }

    @Override
    public DynaBean findProductDevelopRole(String productId) {
        return metaService.selectOne("JE_RBAC_ROLE",ConditionsWrapper.builder().eq("SY_PRODUCT_ID",productId));
    }

    @Override
    public List<DynaBean> findProductDevelopRoles(List<String> productIdList) {
        return metaService.select("JE_RBAC_ROLE",ConditionsWrapper.builder().in("SY_PRODUCT_ID",productIdList));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void bindUserToProductRole(String roleId, List<String> userIdList) {
        DynaBean productRole = metaService.selectOne("JE_RBAC_ROLE",ConditionsWrapper.builder().eq("JE_RBAC_ROLE_ID",roleId));
        //账号部门id
        List<DynaBean> accountBeanList = metaService.select("JE_RBAC_VUSERQUERY",ConditionsWrapper.builder().in("JE_RBAC_ACCOUNTDEPT_ID",userIdList));
        if(accountBeanList == null || accountBeanList.isEmpty()){
            return;
        }

        metaService.delete("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder()
                .eq("ACCOUNTROLE_ROLE_ID", roleId));

        DynaBean accountRoleBean;
        for (DynaBean eachAccountDeptBean : accountBeanList) {
            accountRoleBean = new DynaBean("JE_RBAC_ACCOUNTROLE",false);
            accountRoleBean.set("ACCOUNTROLE_ROLE_ID",roleId);
            accountRoleBean.set("ACCOUNTROLE_ROLE_NAME",productRole.getStr("ROLE_NAME"));
            accountRoleBean.set("ACCOUNTROLE_ACCOUNT_ID",eachAccountDeptBean.getStr("ACCOUNT_ID"));
            accountRoleBean.set("ACCOUNTROLE_DEPT_ID",eachAccountDeptBean.getStr("DEPARTMENT_ID"));
            accountRoleBean.set("ACCOUNTROLE_DEPT_NAME",eachAccountDeptBean.getStr("DEPARTMENT_NAME"));
            accountRoleBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
            accountRoleBean.set("SY_STATUS","1");
            metaService.insert(accountRoleBean);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void removeProductRoleUsers(String roleId, List<String> userIdList) {
        //账号部门id TODO
        List<DynaBean> accountBeanList = metaService.select("JE_RBAC_VUSERQUERY",ConditionsWrapper.builder().in("JE_RBAC_ACCOUNTDEPT_ID",userIdList));
        if(accountBeanList == null || accountBeanList.isEmpty()){
            return;
        }
//        List<String> accountIdList = new ArrayList<>();
        for (DynaBean eachAccountBean : accountBeanList) {
//            accountIdList.add(eachAccountBean.getStr("JE_RBAC_ACCOUNT_ID"));
            metaService.delete("JE_RBAC_ACCOUNTROLE",ConditionsWrapper.builder()
                    .eq("ACCOUNTROLE_ROLE_ID",roleId)
                    .eq("ACCOUNTROLE_ACCOUNT_ID",eachAccountBean.getStr("ACCOUNT_ID"))
                    .eq("ACCOUNTROLE_DEPT_ID",eachAccountBean.getStr("DEPARTMENT_ID")));
        }
    }

}